import { cloneElement, isValidElement, useEffect, useState, useRef } from "react";
import React, { createContext, useContext } from "react";
import { HoverHighlightLayer } from "./HoverHighlightLayer";
import { FloatingCircleButton } from "./components";
import { DebugContext, useDebugButtons, useDebugContext } from "./constants";

// 新增通用圆形按钮组件
// todo: data-source新增层级关系,也就是说父组件是谁之类的
// todo: 可选项,data-source 只出现自定义组件,库组件并不进行同样的操作

export const HoverPickerButton: React.FC<{ picking: boolean; onTogglePick: () => void }> = ({ picking, onTogglePick }) => {
  return (
    <button onClick={onTogglePick} style={{ background: picking ? "red" : undefined }}>
      {picking ? "退出拾取" : "拾取元素"}
    </button>
  );
};

export const ParentStackContext = createContext<string[]>([]);

function getDisplayName(node: React.ReactElement) {
  return typeof node.type === "string"
    ? node.type
    : (node.type as any).displayName || (node.type as any).name || "Anonymous";
}

export function DevTools({ children }: { children?: React.ReactNode }) {
  const [showBorder, setShowBorder] = useState(false);
  const [picking, setPicking] = useState(false);
  const [isExpanded, setIsExpanded] = useState(true);
  const [position, setPosition] = useState({ right: 32, bottom: 32 });
  const debugTools = useDebugButtons()
  const {buttons} = useDebugContext()

  const dragInfo = useRef({
    isDragging: false,
    startX: 0,
    startY: 0,
    startRight: 0,
    startBottom: 0,
    didMove: false,
  });

  const [transformedChildren, setTransformedChildren] = useState(children);
  const [transformers, setTransformers] = useState<
      ((node: React.ReactNode, stack: string[]) => React.ReactNode)[]
  >([]);

  // 递归应用所有变换器
  const processChildren = (
      node: React.ReactNode,
      parentStack: string[] = []
  ): React.ReactNode => {
      if (!node) return node;

      if (Array.isArray(node)) {
          return node.map(child => processChildren(child, parentStack));
      }

      if (isValidElement(node)) {
          const displayName = getDisplayName(node);
          const currentStack = [...parentStack, displayName];
          
          // 应用所有变换器
          let result = node.props.children 
              ? processChildren(node.props.children, currentStack)
              : node.props.children;

          transformers.forEach(transform => {
              result = transform(result, currentStack);
          });

          return cloneElement(node, {
              ...node.props,
              children: result
          });
      }

      return node;
  };

  useEffect(() => {
      setTransformedChildren(processChildren(children));
  }, [children, transformers]);

  // 递归为所有子元素包裹边框
  function wrapWithBorder(node: React.ReactNode, parentStack: string[] = []): React.ReactNode {
    if (!node) return node;
    if (Array.isArray(node)) {
      return node.map((child) => wrapWithBorder(child, parentStack));
    }
    if (isValidElement(node)) {
      if ((node.type as any) === DevTools) return node;
      const displayName = getDisplayName(node);
      const newStack = [...parentStack, displayName];
      // 只要有 data-source 就加 data-source-stack
      const extraProps = node.props["data-source"]
        ? { "data-source-stack": JSON.stringify(newStack) }
        : {};
      return (
        <ParentStackContext.Provider value={newStack}>
          {cloneElement(
            node,
            {
              ...node.props,
              ...extraProps,
              style: showBorder
                ? { border: '1px solid red', background: 'rgba(255,0,0,0.08)', position: node.props.style?.position || undefined, ...node.props.style }
                : node.props.style
            },
            node.props.children ? wrapWithBorder(node.props.children, newStack) : node.props.children
          )}
        </ParentStackContext.Provider>
      );
    }
    return node;
  }

  const handleMouseDown = (e: React.MouseEvent) => {
    // e.stopPropagation();
    dragInfo.current = {
      isDragging: true,
      startX: e.clientX,
      startY: e.clientY,
      startRight: position.right,
      startBottom: position.bottom,
      didMove: false,
    };
    window.addEventListener('mousemove', handleMouseMove);
    window.addEventListener('mouseup', handleMouseUp);
  };

  const handleMouseMove = (e: MouseEvent) => {
    if (!dragInfo.current.isDragging) return;

    const dx = e.clientX - dragInfo.current.startX;
    const dy = e.clientY - dragInfo.current.startY;

    if (!dragInfo.current.didMove && (Math.abs(dx) > 5 || Math.abs(dy) > 5)) {
      dragInfo.current.didMove = true;
    }

    setPosition({
      right: dragInfo.current.startRight - dx,
      bottom: dragInfo.current.startBottom - dy,
    });
  };

  const handleMouseUp = () => {
    if (dragInfo.current.isDragging) {
      dragInfo.current.isDragging = false;
      window.removeEventListener('mousemove', handleMouseMove);
      window.removeEventListener('mouseup', handleMouseUp);
    }
  };

  const handleButtonClick = () => {
    if (!dragInfo.current.didMove) {
      setIsExpanded((v) => !v);
    }
     // After a click, reset didMove.
    dragInfo.current.didMove = false;
  };


  return (
    <DebugContext.Provider value={debugTools}>
      <div style={{ position: 'relative' }}>
        {/* 子元素上方的图层 */}
        <div
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            pointerEvents: 'none',
            zIndex: 9999,
          }}
        >
          {/* 右下角悬浮圆形按钮组 */}
          <div
            style={{
              position: 'absolute',
              right: position.right,
              bottom: position.bottom,
              zIndex: 10000,
              display: 'flex',
              flexDirection: 'column',
              gap: 16,
              pointerEvents: 'auto',
            }}
          >
            {isExpanded && buttons.map((item)=>{
              
              return <></>
            })}
            {isExpanded && (<>
              
              <FloatingCircleButton
                style={{ background: picking ? "red" : '#fff' }}
                title={picking ? "退出拾取" : "拾取元素"}
                onClick={() => setPicking(v => !v)}
              >
                <svg  width="24" height="24" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1472">
                  <path 
                    d="M827.84 572.64L560 476a20 20 0 0 0-25.6 25.6L631 769.51c5.79 16 27.7 17.94 36.17 3.15l36.37-63.5A20 20 0 0 1 735 705l116.78 116.73a20 20 0 0 0 28.29 0 20 20 0 0 0 0-28.29L763.3 676.68a20 20 0 0 1 4.2-31.5l63.5-36.37c14.79-8.47 12.88-30.38-3.16-36.17z m38.45-508.42H158.45a60 60 0 0 0-60 60v775.85a60 60 0 0 0 60 60h396.83A14.72 14.72 0 0 0 570 945.35a17.58 17.58 0 0 0-17.57-17.58H155.74a25 25 0 0 1-25-25V121.52a25 25 0 0 1 25-25H869a25 25 0 0 1 25 25v324.33A17.15 17.15 0 0 0 911.15 463a15.14 15.14 0 0 0 15.14-15.14V124.22a60 60 0 0 0-60-60z" 
                    fill="#333333" 
                    p-id="1473"
                  >
                  </path>
                </svg>
              </FloatingCircleButton>
              {/* 显示/关闭边框按钮 */}
              <FloatingCircleButton
                style={{
                  background: showBorder ? 'rgba(255,0,0,0.2)' : '#fff',
                  color: showBorder ? 'red' : '#333',
                }}
                title={showBorder ? '关闭边框' : '显示边框'}
                onClick={() => setShowBorder((v) => !v)}
              >
                {showBorder ? (
                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                    <rect x="4" y="4" width="16" height="16" rx="3" stroke="red" strokeWidth="2" />
                    <line x1="6" y1="6" x2="18" y2="18" stroke="red" strokeWidth="2" />
                  </svg>
                ) : (
                  <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                    <rect x="4" y="4" width="16" height="16" rx="3" stroke="#333" strokeWidth="2" />
                  </svg>
                )}
              </FloatingCircleButton>
            </>)}
            <FloatingCircleButton
              onMouseDown={handleMouseDown}
              onClick={handleButtonClick}
              title={isExpanded ? "收起" : "展开"}
              style={{ 
                cursor: 'move',
                transition: 'transform 0.5s ease',
                transform: isExpanded ? 'rotate(0deg)' : 'rotate(180deg)'
              }}
            >
              <svg 
                width="24" 
                height="24" 
                viewBox="0 0 24 24" 
                fill="none" 
                xmlns="http://www.w3.org/2000/svg"
                style={{
                  // 添加图标动画
                  transition: 'transform 0.5s ease',
                  transform: isExpanded ? 'rotate(0deg)' : 'rotate(180deg)'
                }}
              >
                {isExpanded ? (
                  <path d="M7 10L12 15L17 10" stroke="#333" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                ) : (
                  <path d="M7 14L12 9L17 14" stroke="#333" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
                )}
              </svg>
            </FloatingCircleButton>
          </div>
          {/* 传递 picking 状态 */}
          <HoverHighlightLayer picking={picking} />
        </div>
        {/* 包裹后的子元素 */}
        <div style={{ position: 'relative', zIndex: 1 }}>
          {showBorder ? wrapWithBorder(children) : children}
        </div>
      </div>
    </DebugContext.Provider>
  );
}

export const Debugger = DevTools;
